#include "windowmanager.h"
#include <QDebug>
#include "window.h"

WindowManager::WindowManager(QObject *parent)
    :QObject(parent)
    ,last_auto_id_(0)
    ,active_window_(NULL)
{

}

WindowManager::~WindowManager()
{

}

bool WindowManager::addWindow(Window *w)
{
    if(!w) return false;

    if(w->id()==w->invalidID())
        w->setID(nextID());

    if(windows_.contains(w->id())){
        return false;
    }

    windows_.insert(w->id(), w);
    w->setWindowManager(this);

    connect(w, &Window::visiableChanged, this, &WindowManager::onWindowVisiableChanged);

    return true;
}

Window *WindowManager::activeWindow() const
{
    return active_window_;
}

quint32 WindowManager::nextID()
{
    while(windows_.contains(last_auto_id_)||last_auto_id_==Element::invalidID())
        ++last_auto_id_;

    return last_auto_id_;
}

void WindowManager::setDefaultHandle(const WindowManager::Handle &h)
{
    default_handle_ = h;
}

bool WindowManager::switchWindowTo(quint32 id)
{
    Window *next_window = windows_.value(id);

    if(active_window_){
        active_window_->postLoad(this);
        active_window_->setVisiable(false);
        active_window_->update();
    }
    if(next_window){
        next_window->preLoad(this);
        next_window->setVisiable(true);
        next_window->update();
        active_window_ = next_window;
        return true;
    }

    return false;
}

void WindowManager::onKeyboardEvent(int key, int value)
{
    if(Left==key||Right==key){
        emit moveEvent(MoveDirection(key));
    }else if(active_window_&&active_window_->isBindKeyInWindow(key)){
        emit keyEvent(key, value);
    }else{
        if(default_handle_) default_handle_(key, value);
    }
}

void WindowManager::onWindowVisiableChanged(bool visiable)
{
    Window* w = qobject_cast<Window*>(sender());
    if(!w){
        qWarning() << Q_FUNC_INFO << "Error signal sender!";
        return;
    }
    if(visiable){
        if(active_window_!=w)
            switchWindowTo(w->id());
    }else{
        if(active_window_==w)
            switchWindowTo(w->invalidID());
    }
}
